/*
*	Copyright (C) 2014  Julio Montes, Mario Carrillo
*	
*	Julio Montes e-mail: imc.coder@gmail.com 
*
*	Mario Carrillo e-mail: mario_90ago@live.com.mx
*
*	BSD 3-Clause License
*/

#include "include/iaEditorManager.h"

#include "sdk/include/editor.h"
#include "sdk/include/cfgmgr.h"
#include "include/iaManager.h"
#include "sdk/include/filecfg.h"
#include "sdk/include/lexermgr.h"
#include "sdk/include/lexer.h"
#include "include/iaMainFrame.h"

BEGIN_EVENT_TABLE( iaEditorManager, wxAuiNotebook )
    EVT_AUINOTEBOOK_PAGE_CLOSE( wxID_ANY, iaEditorManager::OnPageClose )
    EVT_SCI_SAVEPOINTREACHED( wxID_ANY, iaEditorManager::OnSavePointReached )
    EVT_SCI_SAVEPOINTLEFT( wxID_ANY, iaEditorManager::OnSavePointLeft )
END_EVENT_TABLE()

iaEditorManager::iaEditorManager( wxWindow *parent )
    : wxAuiNotebook( parent, iaID_EDITOR_MANAGER, wxDefaultPosition, wxDefaultSize, wxAUI_NB_DEFAULT_STYLE | wxAUI_NB_CLOSE_ON_ALL_TABS )
{

}

iaEditorManager::~iaEditorManager()
{

}


int iaEditorManager::FindEditor( const wxString &fileName ) const
{
    for( size_t i=0; i<GetPageCount(); ++i )
    {
        if( static_cast<sdk::Editor *>( GetPage( i ) )->GetFileName() == fileName )
            return i;
    }

    return -1;
}

bool iaEditorManager::SaveEditorAs()
{
     wxFileDialog dlg( this, wxT( "Save file as..." ), wxT( "" ), wxT( "" ), wxT( "*" ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );

    int res = dlg.ShowModal();

    if( res != wxID_OK )
        return false;

    sdk::Editor *editor = GetCurrentEditor();
    editor->SetReadOnly( false );
    const wxString fileName = dlg.GetPath();
    SetPageText( GetPageIndex( editor ), wxT( '*' ) + fileName.AfterLast( wxT( '/' ) ) );
    editor->SetLexer( sdk::LexerManager::Get()->GetLexerByFileMask( fileName.AfterLast( '.' ) ) );
    editor->LoadSettings();
    editor->SetFileName( fileName );
    editor->SaveFile( fileName );

    return true;
}

bool iaEditorManager::SaveCurrentEditor()
{
    return SaveEditor( GetCurrentEditor() );
}

bool iaEditorManager::SaveAllEditors()
{
    for( size_t i=0; i<GetPageCount(); ++i )
        if( !SaveEditor( static_cast<sdk::Editor *>( GetPage( i ) ) ) )
            return false;

    return true;
}

bool iaEditorManager::SaveEditor( const wxString &fileName )
{
    const int index = FindEditor( fileName );

    if( index != -1 )
        return SaveEditor( dynamic_cast<sdk::Editor *>( GetPage( index ) ) );

    return true;
}

bool iaEditorManager::SaveEditor( sdk::Editor *editor )
{
    if( editor->GetModify() )
    {
        wxString fileName = editor->GetFileName();

        if( fileName == wxEmptyString )
        {
            SetSelection( GetPageIndex( editor ) );

            wxFileDialog dlg( this, wxT( "Save file..." ), wxT( "" ), wxT( "" ), wxT( "*" ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );

            int res = dlg.ShowModal();

            if( res != wxID_OK )
                return false;

            fileName = dlg.GetPath();
            SetPageText( GetPageIndex( editor ), wxT( '*' ) + fileName.AfterLast( wxT( '/' ) ) );
            editor->SetLexer( sdk::LexerManager::Get()->GetLexerByFileMask( fileName.AfterLast( '.' ) ) );
            editor->LoadSettings();
            editor->SetFileName( fileName );
        }

        if( sdk::ConfigManager::Get()->GetFile( sdk::Editor::s_fileConfig )->ReadBool( wxT( "/config/general/eofoptions/striptb" ), true ) )
                editor->StripTrailingSpaces();

        if( sdk::ConfigManager::Get()->GetFile( sdk::Editor::s_fileConfig )->ReadBool( wxT( "/config/general/eofoptions/endwithbl" ), true ) )
        {
            wxString lastLine( editor->GetLine( editor->GetLineCount()-1 ) );
            if( lastLine.Trim() != wxEmptyString )
                editor->AppendText( wxT( "\n" ) );
        }

        editor->SaveFile( fileName );
    }

    return true;
}


bool iaEditorManager::CloseCurrentEditor()
{
    return CloseEditor( GetCurrentEditor() );
}

bool iaEditorManager::CloseAllEditors()
{
    const size_t pages = GetPageCount();
    for( size_t i=0; i<pages; ++i )
        if( !CloseEditor( dynamic_cast<sdk::Editor *>( GetPage( 0 ) ) ) )
            return false;

    return true;
}

bool iaEditorManager::CloseEditor( const wxString &fileName )
{
    const int index = FindEditor( fileName );

    if( index != -1 )
        return CloseEditor( dynamic_cast<sdk::Editor *>( GetPage( index ) ) );

    return true;
}

bool iaEditorManager::CloseEditor( sdk::Editor *editor )
{
    const size_t index = GetPageIndex( editor );

    if( editor->GetModify() )
    {
        const int res = wxMessageBox( wxT( "File " ) + editor->GetFileName() +
            wxT( " is modified... Do you want to save the changes?" ), wxT( "Close file" ), wxYES_NO | wxCANCEL );

        if( res == wxCANCEL )
        {
            return false;
        }
        if( res == wxYES )
        {
            if( !SaveEditor( editor ) )
            {
                return false;
            }
        }
    }

    if( GetPageCount() == 0 )
    {
        wxStatusBar *sbar = iaManager::Get()->GetMainFrame()->GetStatusBar();
        sbar->SetStatusText( wxT( "Welcome to IDEALL" ), 0 );
        sbar->SetStatusText( wxEmptyString, 1 );
        sbar->SetStatusText( wxEmptyString, 2 );
        sbar->SetStatusText( wxEmptyString, 3 );
        sbar->SetStatusText( wxEmptyString, 4 );
        sbar->SetStatusText( wxEmptyString, 5 );
    }

    DeletePage( index );

    //HOTFIX: for reset the status bar
    if( GetPageCount() == 0 )
    {
        iaManager::Get()->GetMainFrame()->ResetStatusBar();
    }

    return true;
}

sdk::Editor *iaEditorManager::GetCurrentEditor() const
{
    return dynamic_cast<sdk::Editor *>( GetPage( GetSelection() ) );
}

sdk::Editor *iaEditorManager::GetEditor( const wxString &fileName ) const
{
    int index = FindEditor( fileName );
    if( index != -1 )
        return dynamic_cast<sdk::Editor *>( GetPage( index ) );

    return NULL;
}

void iaEditorManager::OpenFile( const wxString &fileName, const wxString &title, const wxBitmap &image )
{
    int index = FindEditor( fileName );
    if( index != -1 )
        SetSelection( index );

    else
    {
        sdk::Editor *se = new sdk::Editor( this, wxID_ANY );
        se->SetFileName( fileName );
        se->LoadFile( fileName );
        se->SetLexer( sdk::LexerManager::Get()->GetLexerByFileMask( fileName.AfterLast( '.' ) ) );
        se->LoadSettings();
        se->SetSavePoint();

//        struct stat fileStat;
//        if( stat( fileName.char_str(), &fileStat) > -1 )
//            if( fileStat.st_uid != 0 || !(fileStat.st_mode & S_IWUSR) );
//                se->SetReadOnly( true );
        /** REVISAR SI EL ARCHIVO PUEDE SER MODIFICADO PARA VOLVERLO EDITABLE O NO EDITABLE**/

        if( title != wxEmptyString )
            AddPage( se, title, true, image );
        else
            AddPage( se, fileName.AfterLast( wxT( '/' ) ), true, image );
    }
}

void iaEditorManager::NewFile()
{
    sdk::Editor *se = new sdk::Editor( this, wxID_ANY );
    se->LoadSettings();
    AddPage( se, wxT( "Untitled" ), true );
}

int iaEditorManager::SetSelectionEditor( const wxString &fileName )
{
    int index = FindEditor( fileName );

    if( index != -1 )
        SetSelection( index );

    return index;
}






void iaEditorManager::OnPageClose( wxAuiNotebookEvent &evt )
{
    const int index = evt.GetSelection();
    CloseEditor( dynamic_cast<sdk::Editor *>( GetPage( index ) ) );
    evt.Veto();
}

void iaEditorManager::OnSavePointReached( wxScintillaEvent &evt )
{
    const int index = GetPageIndex( dynamic_cast<sdk::Editor *>( evt.GetEventObject() ) );
    const wxString title = GetPageText( index );
    SetPageText( index, title.AfterFirst( wxT( '*' ) ) );

    evt.Skip();
}

void iaEditorManager::OnSavePointLeft( wxScintillaEvent &evt )
{
    const int index = GetPageIndex( dynamic_cast<sdk::Editor *>( evt.GetEventObject() ) );
    const wxString title = GetPageText( index );
    SetPageText( index, wxT( '*' ) + title );

    evt.Skip();
}
